home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / comm / mail / Mutt089src.lha / Mutt-0.89i-AMIGA / src / signal.c < prev    next >
C/C++ Source or Header  |  1998-01-28  |  5KB  |  194 lines

  1. /*
  2.  * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
  3.  * 
  4.  *     This program is free software; you can redistribute it and/or modify
  5.  *     it under the terms of the GNU General Public License as published by
  6.  *     the Free Software Foundation; either version 2 of the License, or
  7.  *     (at your option) any later version.
  8.  * 
  9.  *     This program is distributed in the hope that it will be useful,
  10.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *     GNU General Public License for more details.
  13.  * 
  14.  *     You should have received a copy of the GNU General Public License
  15.  *     along with this program; if not, write to the Free Software
  16.  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  */ 
  18.  
  19. #include "mutt.h"
  20. #include "mutt_curses.h"
  21.  
  22. #include <signal.h>
  23. #include <string.h>
  24.  
  25. static sigset_t Sigset;
  26. static int IsEndwin = 0;
  27.  
  28. /* Attempt to catch "ordinary" signals and shut down gracefully. */
  29. RETSIGTYPE mutt_exit_handler (int sig)
  30. {
  31.   curs_set (1);
  32.   endwin (); /* just to be safe */
  33. #if SYS_SIGLIST_DECLARED
  34.   printf("Caught %s...  Exiting.\n", sys_siglist[sig]);
  35. #else
  36. #if (__sun__ && __svr4__)
  37.   printf("Caught %s...  Exiting.\n", _sys_siglist[sig]);
  38. #else
  39.   printf("Caught signal %d...  Exiting.\n", sig);
  40. #endif
  41. #endif
  42.   exit (0);
  43. }
  44.  
  45. RETSIGTYPE sighandler (int sig)
  46. {
  47.   switch (sig)
  48.   {
  49.     case SIGTSTP: /* user requested a suspend */
  50.       if(!option(OPTSUSPEND))
  51.         break;
  52.       IsEndwin = isendwin ();
  53.       curs_set (1);
  54.       if (!IsEndwin)
  55.     endwin ();
  56.       kill (0, SIGSTOP);
  57.  
  58.     case SIGCONT:
  59.       if (!IsEndwin)
  60.     refresh ();
  61.       mutt_curs_set (-1);
  62.       break;
  63.  
  64. #if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)
  65.     case SIGWINCH:
  66.       Signals |= S_SIGWINCH;
  67.       break;
  68. #endif
  69.     case SIGINT:
  70.       Signals |= S_INTERRUPT;
  71.       break;
  72.  
  73.     default:
  74.       break;
  75.   }
  76. }
  77.  
  78. #ifdef USE_SLANG_CURSES
  79. int mutt_intr_hook (void)
  80. {
  81.   return (-1);
  82. }
  83. #endif /* USE_SLANG_CURSES */
  84.  
  85. void mutt_signal_init (void)
  86. {
  87.   struct sigaction act;
  88.  
  89.   memset (&act, 0, sizeof (struct sigaction));
  90.  
  91.   act.sa_handler = SIG_IGN;
  92.   sigaction (SIGPIPE, &act, 0);
  93.  
  94.   act.sa_handler = mutt_exit_handler;
  95.   sigaction (SIGTERM, &act, 0);
  96.   sigaction (SIGHUP, &act, 0);
  97.  
  98.   act.sa_handler = sighandler;
  99. #ifdef SA_INTERRUPT
  100.   /* POSIX.1 uses SA_RESTART, but SunOS 4.x uses this instead */
  101.   act.sa_flags = SA_INTERRUPT;
  102. #endif
  103.   sigaction (SIGCONT, &act, 0);
  104.   sigaction (SIGINT, &act, 0);
  105.  
  106.   /* SIGTSTP is the one signal in which we want to restart a system call if it
  107.    * was interrupted in progress.  This is especially important if we are in
  108.    * the middle of a system() call, like if the user is editing a message.
  109.    * Otherwise, the system() will exit when SIGCONT is received and Mutt will
  110.    * resume even though the subprocess may not be finished.
  111.    */
  112. #ifdef SA_RESTART
  113.   act.sa_flags = SA_RESTART;
  114. #else
  115.   act.sa_flags = 0;
  116. #endif
  117.   sigaction (SIGTSTP, &act, 0);
  118.  
  119. #if defined (USE_SLANG_CURSES) || defined (HAVE_RESIZETERM)
  120.   sigaction (SIGWINCH, &act, 0);
  121. #endif
  122.  
  123. #ifdef USE_SLANG_CURSES
  124.   /* This bit of code is required because of the implementation of
  125.    * SLcurses_wgetch().  If a signal is received (like SIGWINCH) when we
  126.    * are in blocking mode, SLsys_getkey() will not return an error unless
  127.    * a handler function is defined and it returns -1.  This is needed so
  128.    * that if the user resizes the screen while at a prompt, it will just
  129.    * abort and go back to the main-menu.
  130.    */
  131.   SLang_getkey_intr_hook = mutt_intr_hook;
  132. #endif
  133. }
  134.  
  135. /* signals which are important to block while doing critical ops */
  136. void mutt_block_signals (void)
  137. {
  138.   if (!option (OPTSIGNALSBLOCKED))
  139.   {
  140.     sigemptyset (&Sigset);
  141.     sigaddset (&Sigset, SIGINT);
  142.     sigaddset (&Sigset, SIGWINCH);
  143.     sigaddset (&Sigset, SIGHUP);
  144.     sigaddset (&Sigset, SIGTERM);
  145.     sigaddset (&Sigset, SIGTSTP);
  146.     sigprocmask (SIG_BLOCK, &Sigset, 0);
  147.     set_option (OPTSIGNALSBLOCKED);
  148.   }
  149. }
  150.  
  151. /* restore the previous signal mask */
  152. void mutt_unblock_signals (void)
  153. {
  154.   if (option (OPTSIGNALSBLOCKED))
  155.   {
  156.     sigprocmask (SIG_UNBLOCK, &Sigset, 0);
  157.     unset_option (OPTSIGNALSBLOCKED);
  158.   }
  159. }
  160.  
  161. void mutt_block_signals_system (void)
  162. {
  163.   struct sigaction sa;
  164.  
  165.   if (! option (OPTSIGNALSBLOCKED))
  166.   {
  167.     sa.sa_handler = SIG_IGN;
  168.     sa.sa_flags = 0;
  169.     sigaction (SIGINT, &sa, NULL);
  170.     sigaction (SIGQUIT, &sa, NULL);
  171.     sigemptyset (&Sigset);
  172.     sigaddset (&Sigset, SIGCHLD);
  173.     sigprocmask (SIG_BLOCK, &Sigset, 0);
  174.     set_option (OPTSIGNALSBLOCKED);
  175.   }
  176. }
  177.  
  178. void mutt_unblock_signals_system (int catch)
  179. {
  180.   struct sigaction sa;
  181.  
  182.   if (option (OPTSIGNALSBLOCKED))
  183.   {
  184.     sa.sa_flags = 0;
  185.     sa.sa_handler = mutt_exit_handler;
  186.     sigaction (SIGQUIT, &sa, NULL);
  187.     if (catch)
  188.       sa.sa_handler = sighandler;
  189.     sigaction (SIGINT, &sa, NULL);
  190.     sigprocmask (SIG_UNBLOCK, &Sigset, NULL);
  191.     unset_option (OPTSIGNALSBLOCKED);
  192.   }
  193. }
  194.